package com.cq.hd.member.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cq.hd.common.enums.biz.ConfigSettingTypeEnum;
import com.cq.hd.member.api.dto.ConfigSettingQueryDto;
import com.cq.hd.member.api.dto.ConfigSettingUpdateDto;
import com.cq.hd.member.api.vo.ConfigSettingVo;
import com.cq.hd.member.mapper.TbConfigSettingMapper;
import com.cq.hd.member.po.TbConfigSettingPo;
import com.cq.hd.member.service.TbConfigSettingService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 配置设置表 服务实现类
 * </p>
 */
@Service
public class TbConfigSettingServiceImpl extends ServiceImpl<TbConfigSettingMapper, TbConfigSettingPo> implements TbConfigSettingService {

    @Override
    public String getUserConfigValue(Long userId, String configKey) {
        TbConfigSettingPo configSettingPo = getByConfigKey(userId, configKey);
        if (configSettingPo != null) {
            return configSettingPo.getConfigValue();
        }
        return null;
    }

    @Override
    public String getUserConfigValueOfDefault(Long userId, String configKey) {
        TbConfigSettingPo configSettingPo = getByConfigKey(userId, configKey);
        if (configSettingPo == null) {
            configSettingPo = getByConfigKey(0L, configKey);
        }
        return configSettingPo.getConfigValue();
    }

    @Override
    public TbConfigSettingPo getByConfigKey(Long userId, String configKey) {
        return this.getOne(new LambdaQueryWrapper<TbConfigSettingPo>()
                .eq(TbConfigSettingPo::getUserId, userId)
                .eq(TbConfigSettingPo::getConfigKey, configKey));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveOrUpdateConfig(TbConfigSettingPo configSetting) {
        if (configSetting.getId() == null) {
            configSetting.setCreateTime(LocalDateTime.now());
        }
        configSetting.setUpdateTime(LocalDateTime.now());
        return this.saveOrUpdate(configSetting);
    }

    @Override
    public String getConfigValueByType(String configType) {
        TbConfigSettingPo config = this.getOne(new LambdaQueryWrapper<TbConfigSettingPo>()
                .eq(TbConfigSettingPo::getConfigType, configType)
                .last("LIMIT 1"));
        return config != null ? config.getConfigValue() : null;
    }

    @Override
    public void setConfigValue(ConfigSettingUpdateDto configSettingUpdateDto) {
        String configKey = configSettingUpdateDto.getConfigKey();
        Long userId = configSettingUpdateDto.getUserId();
        TbConfigSettingPo configSettingPo = getByConfigKey(userId, configKey);
        if (configSettingPo == null) {
            TbConfigSettingPo defaultConfigSettingPo = getByConfigKey(0L, configKey);
            configSettingPo = BeanUtil.copyProperties(defaultConfigSettingPo, TbConfigSettingPo.class);
            configSettingPo.setId(null);
            configSettingPo.setUserId(configSettingUpdateDto.getUserId());
            configSettingPo.setConfigValue(configSettingUpdateDto.getConfigValue());
            configSettingPo.setCreateTime(LocalDateTime.now());
            baseMapper.insert(configSettingPo);
        } else {
            configSettingPo.setConfigValue(configSettingUpdateDto.getConfigValue());
            configSettingPo.setUpdateTime(LocalDateTime.now());
            baseMapper.updateById(configSettingPo);
        }
    }

    @Override
    public List<ConfigSettingVo> getUserConfigOrDefault(ConfigSettingQueryDto configSettingQueryDto) {
        Long userId = configSettingQueryDto.getUserId();
        List<String> configKeys = configSettingQueryDto.getConfigKeys();
        if (CollectionUtils.isEmpty(configKeys)) {
            return Collections.emptyList();
        }

        // 查询用户配置
        List<TbConfigSettingPo> userConfigs = this.list(new LambdaQueryWrapper<TbConfigSettingPo>()
                .eq(TbConfigSettingPo::getUserId, userId)
                .in(TbConfigSettingPo::getConfigKey, configKeys));

        // 将用户配置转换为Map，key为configKey
        Map<String, TbConfigSettingPo> userConfigMap = userConfigs.stream()
                .collect(Collectors.toMap(
                        TbConfigSettingPo::getConfigKey,
                        Function.identity(),
                        (v1, v2) -> v1));

        // 获取未配置的key
        List<String> unconfiguredKeys = configKeys.stream()
                .filter(key -> !userConfigMap.containsKey(key))
                .collect(Collectors.toList());

        // 如果有未配置的key，查询默认配置
        if (!unconfiguredKeys.isEmpty()) {
            List<TbConfigSettingPo> defaultConfigs = this.list(new LambdaQueryWrapper<TbConfigSettingPo>()
                    .eq(TbConfigSettingPo::getUserId, 0L)
                    .in(TbConfigSettingPo::getConfigKey, unconfiguredKeys));

            // 将默认配置添加到Map中
            defaultConfigs.forEach(config -> 
                userConfigMap.putIfAbsent(config.getConfigKey(), config));
        }

        // 按照传入的configKeys顺序转换为VO列表
        List<ConfigSettingVo> configSettingList = configKeys.stream()
                .map(key -> {
                    TbConfigSettingPo config = userConfigMap.get(key);
                    if (config != null) {
                        ConfigSettingVo vo = new ConfigSettingVo();
                        BeanUtils.copyProperties(config, vo);
                        return vo;
                    }
                    return null;
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        setConfigSettingShowName(configSettingList);

        return configSettingList;
    }

    private void setConfigSettingShowName(List<ConfigSettingVo> dataList) {
        if (CollectionUtils.isEmpty(dataList)) {
            return;
        }
        for (ConfigSettingVo configSettingVo : dataList) {
            if (ConfigSettingTypeEnum.PERCENTAGE.name().equals(configSettingVo.getConfigType())) {
                String value = configSettingVo.getConfigValue();
                if (value != null) {
                    configSettingVo.setShowValue(convertToPercentage(value));
                }
            }
        }
    }

    private String convertToPercentage(String decimalStr) {
        try {
            // 将字符串解析为浮点数，并乘以100
            double value = Double.parseDouble(decimalStr) * 100;
            // 格式化为整数百分比并返回
            return String.format("%.0f%%", value);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("Invalid decimal string: " + decimalStr, e);
        }
    }

}